package com.yfyszk.kingbird.upload;



import com.yfyszk.kingbird.common.constants.CommonFileConstant;
import com.yfyszk.kingbird.common.utils.DateUtils;
import com.yfyszk.kingbird.common.utils.IdWorkerUtils;
import com.yfyszk.kingbird.common.utils.PlatformUtils;
import com.yfyszk.kingbird.common.vo.UploadFileVO;
import com.yfyszk.kingbird.exception.GlobalServiceException;
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * 类名称：UploadFileUtils 类描述：UploadFileUtils 文件上传工具类 创建人：wgc 创建时间：2018-03-31
 * 上午12:44:20
 */

@Component
public class UploadFileUtils {
    // 文件允许格式
    private static String[] allowFiles = {"png", "jpg", "pdf", "txt", "doc", "docx", "xls", "xlsx", "pdf",
            "rar", "zip", "blob", "avi", "mov", "rmvb", "rm", "flv", "mp4", "3gp", "apk"};
    private static Logger log = LoggerFactory.getLogger(UploadFileUtils.class);
    // 最大100M
    static long maxSize = 1024 * 1024 * 100;

    /**
     * @param request
     * @return
     * @throws Exception
     */
    public static UploadFileVO uploadFileOne(HttpServletRequest request, String fileLinuxPath) throws Exception {
        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
        String filePath = "";
        String fileName = "";// 文件名称
        FileOutputStream fos = null;
        UploadFileVO file = null;
        String fileUrl = null;
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                multiRequest.getSession().getServletContext());
        if (multipartResolver.isMultipart(multiRequest)) {
            log.info("{******************开始上传**********************}");
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                List<MultipartFile> multipartFiles = multiRequest.getFiles(iter.next());
                if (multipartFiles != null && !multipartFiles.isEmpty()) {
                    for (final MultipartFile multipartFile : multipartFiles) {
                        file = new UploadFileVO();
                        fileName = multipartFile.getOriginalFilename();// 获取上传的文件名字
                        String uniqueImageName = IdWorkerUtils.getInstance().nextId()+"";
                        String uuidImage = uniqueImageName;
                        String suffixName = multipartFile.getOriginalFilename()
                                .substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1);
                        log.info("suffixName:{}", suffixName);
                        // 如果是图片
                        if (suffixName.toLowerCase().equals("jpg") || suffixName.toLowerCase().equals("png")) {
                            filePath = File.separator + DateUtils.nowDayTimeStamp() + File.separator + uniqueImageName
                                    + File.separator + uniqueImageName + ".jpg";
                        } else {
                            // 如果是文件或视频
                            filePath = File.separator + DateUtils.nowDayTimeStamp() + File.separator + uniqueImageName
                                    + File.separator + fileName;
                        }
                        if (multipartFile.getSize() > maxSize) {
                             throw new GlobalServiceException(1,"文件超过100M");
                        }
                        // 判断文件格式是否包含规定的文件格式
                        if (PlatformUtils.isWindows()) {
                            fileUrl = CommonFileConstant.WINDOWS_FILE_URL + filePath;
                        } else if (PlatformUtils.isLinux()) {
                            fileUrl = fileLinuxPath + filePath;
                        } else if (PlatformUtils.isMac()) {
                            fileUrl = CommonFileConstant.MAC_FILE_URL + filePath;

                        }

                        log.info("-------------------文件创建开始-------------------");
                        try {
                            final File objFile = new File(fileUrl); // 创建对象
                            if (!objFile.exists()) {
                                objFile.mkdir();

                            } else {
                                log.info(fileUrl + "====文件夹已存在");
                            }
                            // 上级文件是否存在
                            // 判断目标文件所在的目录是否存在
                            if (!objFile.getParentFile().exists()) {
                                // 如果目标文件所在的目录不存在，则创建父目录
                                objFile.getParentFile().mkdirs();
                            }
                            multipartFile.transferTo(objFile);
                            log.info("**********上传成功**************");
                            if (checkFileType(suffixName.toLowerCase())) {
                                String filePngFlag = "png";
                                String fileJpgFlag = "jpg";
                                // 如果不是pdf则上传的是图片 并且有缩略图
                                if (filePngFlag.equals(suffixName.toLowerCase()) ||
                                        fileJpgFlag.equals(suffixName.toLowerCase())) {
                                    String thumbnailUrl = null;
                                    String thumbnailPath = File.separator + DateUtils.nowDayTimeStamp() + File.separator
                                            + uniqueImageName + File.separator + uuidImage + ".jpg";
                                    if (PlatformUtils.isWindows()) {
                                        thumbnailUrl = CommonFileConstant.WINDOWS_FILE_URL + thumbnailPath;
                                    } else if (PlatformUtils.isLinux()) {
                                        thumbnailUrl = fileLinuxPath + thumbnailPath;
                                    } else if (PlatformUtils.isMac()) {
                                        thumbnailUrl = CommonFileConstant.MAC_FILE_URL + thumbnailPath;
                                    }
                                    Thumbnails.of(fileUrl).size(200, 200).keepAspectRatio(false).toFile(thumbnailUrl);
                                    log.info("{----------------压缩成功-------------------}");
                                    file.setFileName(fileName);
                                    file.setFileSize(String.valueOf(multipartFile.getSize()));
                                    file.setProjectFileUrl(filePath);// 原图路径
                                    file.setThumbnailUrl(thumbnailPath);// 缩略图路径
                                    file.setSuffixName(suffixName);
                                } else {
                                    file.setFileName(fileName);
                                    file.setFileSize(String.valueOf(multipartFile.getSize()));
                                    file.setProjectFileUrl(filePath);// 文件路径
                                    file.setSuffixName(suffixName);
                                }
                            }

                        } catch (IOException ie) {
                            log.info("上传异常:{}",ie.getMessage());
                            throw new GlobalServiceException(1,"文件上传失败");
                        } finally {
                            // 关闭FileOutputStream对象
                            try {
                                if (fos != null) {
                                    fos.close();
                                }
                            } catch (Exception e) {
                                e.getMessage();
                                e.printStackTrace();
                            }
                        }

                    }

                }

            }
            log.info("上传的文件:【{}】", file);
            return file;
        }
        return file;
    }



    /**
     * @param request
     * @return
     * @throws Exception
     */
    public static UploadFileVO uploadImageOne(HttpServletRequest request, String fileLinuxPath) throws Exception {
        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
        String filePath = "";
        String fileName = "";// 文件名称
        FileOutputStream fos = null;
        UploadFileVO file = null;
        String fileUrl = null;
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                multiRequest.getSession().getServletContext());
        if (multipartResolver.isMultipart(multiRequest)) {
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                List<MultipartFile> multipartFiles = multiRequest.getFiles(iter.next());
                if (multipartFiles != null && !multipartFiles.isEmpty()) {
                    for (final MultipartFile multipartFile : multipartFiles) {
                        file = new UploadFileVO();
                        fileName = multipartFile.getOriginalFilename();// 获取上传的文件名字
                        String uniqueImageName = IdWorkerUtils.getInstance().nextId()+"";
                        String uuidImage = uniqueImageName;
                        String suffixName = multipartFile.getOriginalFilename()
                                .substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1);
                        log.info("suffixName:{}", suffixName);
                        filePath = File.separator + DateUtils.nowDayTimeStamp() + File.separator + uniqueImageName
                                + File.separator + uniqueImageName + ".jpg";
                        if (multipartFile.getSize() > maxSize) {
                            throw new GlobalServiceException(1,"文件超过100M");
                        }
                        if (PlatformUtils.isWindows()) {
                            fileUrl = CommonFileConstant.WINDOWS_FILE_URL + filePath;
                        } else if (PlatformUtils.isLinux()) {
                            fileUrl = fileLinuxPath + filePath;

                        } else if (PlatformUtils.isMac()) {
                            fileUrl = CommonFileConstant.MAC_FILE_URL + filePath;

                        }
                        log.info("------------------文件创建开始----------------------");
                        try {
                            final File objFile = new File(fileUrl); // 创建对象
                            if (!objFile.exists()) {
                                objFile.mkdir();

                            } else {
                                log.info(fileUrl + "====文件夹已存在");
                            }
                            // 上级文件是否存在
                            // 判断目标文件所在的目录是否存在
                            if (!objFile.getParentFile().exists()) {
                                // 如果目标文件所在的目录不存在，则创建父目录
                                objFile.getParentFile().mkdirs();
                            }

                            multipartFile.transferTo(objFile);
                            log.info("**********上传成功**************");
                            String thumbnailUrl = null;
                            String thumbnailPath = File.separator + DateUtils.nowDayTimeStamp() + File.separator
                                    + uniqueImageName + File.separator + uuidImage + ".jpg";
                            if (PlatformUtils.isWindows()) {
                                thumbnailUrl = CommonFileConstant.WINDOWS_FILE_URL + thumbnailPath;
                            } else if (PlatformUtils.isLinux()) {
                                thumbnailUrl = fileLinuxPath + thumbnailPath;

                            } else if (PlatformUtils.isMac()) {
                                thumbnailUrl = CommonFileConstant.MAC_FILE_URL + thumbnailPath;
                            }
                            Thumbnails.of(fileUrl).size(200, 200).keepAspectRatio(false).toFile(thumbnailUrl);
                            log.info("{----------------压缩成功-------------------}");
                            file.setFileName(fileName);
                            file.setFileSize(String.valueOf(multipartFile.getSize()));
                            file.setProjectFileUrl(filePath);// 原图路径
                            file.setThumbnailUrl(thumbnailPath);// 缩略图路径
                            file.setSuffixName(suffixName);
                        } catch (IOException ie) {
                            file.setFileName(fileName);
                            file.setFileSize("0");
                            file.setProjectFileUrl(filePath);// 原图路径
                            file.setThumbnailUrl("");// 缩略图路径
                            file.setSuffixName(suffixName);
                            log.error("上传异常:{}", ie.getMessage());
                            return file;
                        } finally {
                            // 关闭FileOutputStream对象
                            try {
                                if (fos != null) {
                                    fos.close();
                                }
                            } catch (Exception e) {
                                e.getMessage();
                                e.printStackTrace();
                            }
                        }
                    }

                }

            }
            log.info("上传的文件:【{}】", file);
            return file;
        }
        return file;
    }


    /**
     * 文件类型判断
     *
     * @return
     */
    public static boolean checkFileType(String suffixName) {
        Iterator<String> type = Arrays.asList(allowFiles).iterator();
        while (type.hasNext()) {
            String ext = type.next();
            if (suffixName.toLowerCase().equals(ext)) {
                return true;
            }
        }
        return false;
    }


    public static boolean httpDownload(String httpUrl, String saveFile) {
        // 1.下载网络文件
        int byteRead;
        URL url;
        try {
            url = new URL(httpUrl);
        } catch (MalformedURLException e1) {
            throw new GlobalServiceException(1,"下载失败");
        }

        try {
            //2.获取链接
            URLConnection conn = url.openConnection();
            //3.输入流
            InputStream inStream = conn.getInputStream();
            //3.写入文件
            FileOutputStream fs = new FileOutputStream(saveFile);

            byte[] buffer = new byte[4096];
            while ((byteRead = inStream.read(buffer)) != -1) {
                fs.write(buffer, 0, byteRead);
            }
            inStream.close();
            fs.close();
            log.info("************下载成功*****************");
            return true;
        } catch (FileNotFoundException e) {
            throw new GlobalServiceException(1,"下载失败");
        } catch (IOException e) {
            throw new GlobalServiceException(1,"下载失败");
        }

    }

    /**
     * 单例有很多种方式去实现：我采取绝对线程安全的一种方式
     * <p>
     * 静态内部类的方式，去初始化单例
     *
     * @author wgc
     */
    private static class Singleton {

        private static UploadFileUtils instance;

        static {
            instance = new UploadFileUtils();
        }

        public static UploadFileUtils getInstance() {
            return instance;
        }

    }

    /**
     * jvm的机制去保证多线程并发安全
     * <p>
     * 内部类的初始化，一定只会发生一次，不管多少个线程并发去初始化
     *
     * @return
     */
    public static UploadFileUtils getInstance() {
        return Singleton.getInstance();
    }

    /**
     * 初始化的便捷方法
     */
    public static void init() {
        getInstance();
    }


}
